<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    // 每个函数都有一个名为prototype的属性，该属性的类型为对象，该对象被称为原型对象（显式原型对象）。
    // function fn(){
    // }
    // console.log(fn.prototype);// 称为原型对象（显式原型对象）


    // 原型对象拥有constructor属性，该属性我们称其为构造函数,因为它指回构函数本身。
    // function Box(){
    //
    // }
    //
    // console.log(Box.prototype.constructor === Box);// true
    //
    //
    // const obj = new Box();
    // console.log(obj.__proto__ === Box.prototype)
    // console.log(obj.constructor === Box);


    // 给原型对象添加属性(一般都是方法)，函数的所有实例对象自动拥有原型中的属性(方法)
    // function Box(){
    //     this.a = 1;// 增加实例属性a
    // }
    // Box.prototype.run = function(){
    //     console.log("run");
    // }
    // // new 称为 实例化操作符。
    // const obj = new Box();
    // console.log(obj.a);// 1
    // obj.run();


    // 每个实例对象都有一个`__proto__`，可称为隐式原型
    // function Box(){
    //
    // }
    // const obj = new Box();
    // console.log(obj.__proto__);// 隐式原型对象
    // // 实例中的隐式原型对象（__proto__）指向构造函数中的显式原型对象(prototype)
    // console.log(obj.__proto__ === Box.prototype);// true


    // ### 原型链
    // - 所有的实例对象都有`__proto__`属性, 它指向的就是原型对象
    // - 这样通过`__proto__`属性就形成了一个链的结构---->原型链
    // function Box(){
    //
    // }
    // const obj = new Box();
    // console.log(obj.__proto__ === Box.prototype);// true
    // console.log(Box.prototype.__proto__ === Object.prototype);// true
    // console.log(Object.prototype.__proto__);// null



    // - 当查找对象内部的属性/方法时,` js`引擎自动沿着这个原型链查找
    // function Box(){
    //     // this.userName = "zhangsan";
    // }
    // // Box.prototype.userName = "lisi";
    // // Object.prototype.userName = "wangwu";
    // const obj = new Box();
    // console.log(obj.__proto__ === Box.prototype);// true
    // console.log(Box.prototype.__proto__ === Object.prototype);// true
    // console.log(Object.prototype.__proto__);// null
    // console.log(obj.userName);







    // - 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
    function Box(){

    }
    Box.prototype.userName = "zhangsan";
    const obj = new Box();
    obj.userName = "lisi";// 为实例对象obj增加 属性username,值为lisi
    console.log(obj.userName);// lisi
    obj.__proto__.userName = "wangwu";
    console.log(obj.__proto__.userName);// wangwu


</script>
</html>